"""
Case Type   : 共享存储-系统内部工具-dsscmd
Case Name   : dsscmd工具取消软连接
Create At   : 2023/4/19
Owner       : opentestcase019
Description :
    1.创建目录和文件
    2.取消软连接，指定-p path参数为正常的路径
    3.取消软连接，指定-p path参数为不符合规范的路径
    4.取消软连接，指定-U UDS:socket_domain参数为正常值
    5.取消软连接，指定错误的-U UDS:socket_domain参数
    6.取消软连接，指定权限不足的socket_domain
    7.在备机点执行取消软连接
    8.环境清理
Expect      :
    1.创建成功
    2.取消软连接成功
    3.合理报错
    4.取消软连接成功
    5.合理报错Failed to get uds connection.
    6.合理报错Failed to get uds connection.
    7.取消软连接成功
    8.清理成功
History     :
"""
import os
import unittest
from yat.test import Node
from yat.test import macro
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant

Primary_SH = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == Primary_SH.get_node_num(), '单机环境不执行')
class ShareStorageTool(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.standby_node = Node('Standby1DbUser')
        self.common = Common()
        self.constant = Constant()
        self.dir_name = "dir_dsscmd_0029"
        self.file_name = "file_dsscmd_0029"
        self.link_name = "link_dsscmd_0029"
        self.link_name_64chars = \
            "link_dsscmd_0029_link_dsscmd_0029_link_dsscmd_0029_link__64chars"
        self.logger.info("-----获取卷组名-----")
        execute_cmd = f"source {macro.DB_ENV_PATH};dsscmd lsvg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn("Succeed to display lsvg info.", execute_msg, "获取卷组名失败")
        self.vgname = execute_msg.splitlines()[1].split()[0].strip()
        self.logger.info(self.vgname)
        self.dir_path = os.path.join(self.vgname, self.dir_name)
        self.file_path = os.path.join(self.dir_path, self.file_name)
        self.link_path = os.path.join(self.vgname, self.link_name)
        self.link_path_64chars = os.path.join(self.vgname,
                                              self.link_name_64chars)

    def test_sharestorage_tool(self):
        step1 = "-----step1:创建目录和文件;expect:创建成功-----"
        self.logger.info(step1)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd mkdir -p +{self.vgname} -d {self.dir_name};" \
            f"dsscmd touch -p +{self.file_path};"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f'Succeed to make dir, path is +{self.vgname}, dir name '
                      f'is {self.dir_name}.', execute_msg, "执行失败" + step1)
        self.assertIn(f"Succeed to create file, name is +{self.file_path}.",
                      execute_msg, "执行失败" + step1)

        step2 = "-----step2:取消软连接，指定-p path参数为正常的路径;expect:取消软连接成功-----"
        self.logger.info(step2)
        cmd_list = [f'{self.link_path}', f'{self.link_path}$data1',
                    f'{self.link_path}$2']
        for cmd in cmd_list:
            execute_cmd = f"source {macro.DB_ENV_PATH};" \
                f"dsscmd ln -s +{self.file_path} -t +{self.link_path};" \
                f"dsscmd readlink -p +{self.link_path};" \
                f"dsscmd unlink -p +{cmd}"
            self.logger.info(execute_cmd)
            execute_msg = self.common.get_sh_result(self.primary_node,
                                                    execute_cmd)
            self.assertIn(f"Success to link +{self.link_path} "
                          f"to +{self.file_path}.", execute_msg, "执行失败" + step2)
            self.assertIn(f"link: +{self.link_path} link "
                          f"to: +{self.file_path}.",
                          execute_msg, "执行失败" + step2)
            self.assertIn(f"link: +{self.link_path} link "
                          f"to: +{self.file_path}.",
                          execute_msg, "执行失败" + step2)

        step3 = "-----step3:取消软连接，指定-p path参数为不符合规范的路径;expect:合理报错-----"
        self.logger.info(step3)
        cmd_list = [f'+{self.link_path}_not_exists', f'+{self.link_path}$#',
                    f'+{self.link_path}*^%', f'+{self.link_path}@#$',
                    f'{self.link_path}', f'+{self.link_path_64chars}']
        for cmd in cmd_list:
            execute_cmd = f"source {macro.DB_ENV_PATH};" \
                f"dsscmd unlink -p {cmd}"
            self.logger.info(execute_cmd)
            execute_msg = self.common.get_sh_result(self.primary_node,
                                                    execute_cmd)
            if cmd in cmd_list[0:2]:
                self.assertIn(f"does not exist", execute_msg, "执行失败" + step3)
            elif cmd == cmd_list[-2]:
                self.assertIn("decode error , path should start with +.",
                              execute_msg, "执行失败" + step3)
            elif cmd == cmd_list[-1]:
                self.assertIn("Path  decode error name length should less "
                              "than 64", execute_msg, "执行失败" + step3)
            else:
                self.assertIn("decode error , path should be "
                              "[0~9,a~z,A~Z,-,_,/,.]",
                              execute_msg, "执行失败" + step3)

        step4 = "-----step4:取消软连接，指定-U UDS:socket_domain参数为正常值;" \
                "expect:取消软连接成功-----"
        self.logger.info(step4)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd ln -s +{self.file_path} -t +{self.link_path};" \
            f"dsscmd unlink -p +{self.link_path} -U {macro.UDS_PATH}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Success to link +{self.link_path} to "
                      f"+{self.file_path}.", execute_msg, "执行失败" + step4)
        self.assertIn(f"Succeed to unlink +{self.link_path}.",
                      execute_msg, "执行失败" + step4)

        step5 = "-----step5:取消软连接，指定错误的-U UDS:socket_domain参数;" \
                "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step5)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd ln -s +{self.file_path} -t +{self.link_path};" \
            f"dsscmd unlink  -p +{self.link_path} -U {macro.UDS_PATH}.cfg"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step5)

        step6 = "-----step6:取消软连接，指定权限不足的socket_domain;" \
                "expect:合理报错Failed to get uds connection.-----"
        self.logger.info(step6)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"chmod 000 {macro.UDS_PATH[4::]};" \
            f"dsscmd unlink -p +{self.link_path} -U {macro.UDS_PATH};" \
            f"chmod 600 {macro.UDS_PATH[4::]}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(self.constant.failed_to_get_uds_connection,
                      execute_msg, "执行失败" + step6)

        step7 = "-----step7:在备机点执行显示软连接;expect:显示软连接成功-----"
        self.logger.info(step7)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd unlink -p +{self.link_path} -U {macro.UDS_PATH}"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.standby_node, execute_cmd)
        self.assertIn(f"Succeed to unlink +{self.link_path}.",
                      execute_msg, "执行失败" + step7)

    def tearDown(self):
        step8 = "-----step8:环境清理;expect:清理成功-----"
        self.logger.info(step8)
        execute_cmd = f"source {macro.DB_ENV_PATH};" \
            f"dsscmd rmdir -p +{self.dir_path} -r;"
        self.logger.info(execute_cmd)
        execute_msg = self.common.get_sh_result(self.primary_node, execute_cmd)
        self.assertIn(f"Succeed to rm dir, path is +{self.dir_path}",
                      execute_msg, "执行失败" + step8)
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
